home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / toaplan1.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  31KB  |  1,234 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/toaplan1.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7.   There are 4 scrolling layers of graphics, stored in planes of 64x64 tiles.
  8.   Each tile in each plane is assigned a priority between 1 and 15, higher
  9.   numbers have greater priority.
  10.  
  11.   Each tile takes up 32 bits, the format is:
  12.  
  13.   0         1         2         3
  14.   ---- ---- ---- ---- -xxx xxxx xxxx xxxx = tile number (0 - $7fff)
  15.   ---- ---- ---- ---- ?--- ---- ---- ---- = unknown / unused
  16.   ---- ---- --xx xxxx ---- ---- ---- ---- = color (0 - $3f)
  17.   ---- ???? ??-- ---- ---- ---- ---- ---- = unknown / unused
  18.   xxxx ---- ---- ---- ---- ---- ---- ---- = priority (0-$f)
  19.  
  20.   BG Scroll Reg
  21.  
  22.   0         1         2         3
  23.   xxxx xxxx x--- ---- ---- ---- ---- ---- = x
  24.   ---- ---- ---- ---- yyyy yyyy ---- ---- = y
  25.  
  26.  
  27.  Sprite RAM format  (except Rally Bike)
  28.  
  29.   0         1         2         3
  30.   ---- ---- ---- ---- -xxx xxxx xxxx xxxx = tile number (0 - $7fff)
  31.   ---- ---- ---- ---- x--- ---- ---- ---- = hidden
  32.   ---- ---- --xx xxxx ---- ---- ---- ---- = color (0 - $3f)
  33.   ---- xxxx xx-- ---- ---- ---- ---- ---- = sprite number
  34.   xxxx ---- ---- ---- ---- ---- ---- ---- = priority (0-$f)
  35.  
  36.   4         5         6         7
  37.   ---- ---- ---- ---- xxxx xxxx x--- ---- = x
  38.   yyyy yyyy y--- ---- ---- ---- ---- ---- = y
  39.  
  40.   The tiles use a palette of 1024 colors, the sprites use a different palette
  41.   of 1024 colors.
  42.  
  43. ***************************************************************************/
  44.  
  45. #include "driver.h"
  46. #include "palette.h"
  47. #include "vidhrdw/generic.h"
  48. #include "cpu/m68000/m68000.h"
  49.  
  50. #define VIDEORAM1_SIZE    0x1000        /* size in bytes - sprite ram */
  51. #define VIDEORAM2_SIZE    0x100        /* size in bytes - sprite size ram */
  52. #define VIDEORAM3_SIZE    0x4000        /* size in bytes - tile ram */
  53.  
  54. unsigned char *toaplan1_videoram1;
  55. unsigned char *toaplan1_videoram2;
  56. unsigned char *toaplan1_videoram3;
  57. unsigned char *toaplan1_buffered_videoram1;
  58. unsigned char *toaplan1_buffered_videoram2;
  59.  
  60. unsigned char *toaplan1_colorram1;
  61. unsigned char *toaplan1_colorram2;
  62.  
  63. size_t colorram1_size;
  64. size_t colorram2_size;
  65.  
  66. unsigned int scrollregs[8];
  67. unsigned int vblank;
  68. unsigned int num_tiles;
  69.  
  70. unsigned int video_ofs;
  71. unsigned int video_ofs3;
  72.  
  73. int toaplan1_flipscreen;
  74. int tiles_offsetx;
  75. int tiles_offsety;
  76. int layers_offset[4];
  77.  
  78.  
  79. typedef struct
  80.     {
  81.     UINT16 tile_num;
  82.     UINT16 color;
  83.     char priority;
  84.     int xpos;
  85.     int ypos;
  86.     } tile_struct;
  87.  
  88. tile_struct *bg_list[4];
  89.  
  90. tile_struct *tile_list[32];
  91. tile_struct *temp_list;
  92. static int max_list_size[32];
  93. static int tile_count[32];
  94.  
  95. struct osd_bitmap *tmpbitmap1;
  96. static struct osd_bitmap *tmpbitmap2;
  97. static struct osd_bitmap *tmpbitmap3;
  98.  
  99.  
  100. int rallybik_vh_start(void)
  101. {
  102.     int i;
  103.  
  104.     if ((toaplan1_videoram3 = calloc(VIDEORAM3_SIZE * 4, 1)) == 0) /* 4 layers */
  105.     {
  106.         return 1;
  107.     }
  108.  
  109.     logerror("colorram_size: %08x\n", colorram1_size + colorram2_size);
  110.     if ((paletteram = calloc(colorram1_size + colorram2_size, 1)) == 0)
  111.     {
  112.         free(toaplan1_videoram3);
  113.         return 1;
  114.     }
  115.  
  116.     for (i=0; i<4; i++)
  117.     {
  118.         if ((bg_list[i]=(tile_struct *)malloc( 33 * 44 * sizeof(tile_struct))) == 0)
  119.         {
  120.             free(paletteram);
  121.             free(toaplan1_videoram3);
  122.             return 1;
  123.         }
  124.         memset(bg_list[i], 0, 33 * 44 * sizeof(tile_struct));
  125.     }
  126.  
  127.     for (i=0; i<16; i++)
  128.     {
  129.         max_list_size[i] = 8192;
  130.         if ((tile_list[i]=(tile_struct *)malloc(max_list_size[i]*sizeof(tile_struct))) == 0)
  131.         {
  132.             for (i=3; i>=0; i--)
  133.                 free(bg_list[i]);
  134.             free(paletteram);
  135.             free(toaplan1_videoram3);
  136.             return 1;
  137.         }
  138.         memset(tile_list[i],0,max_list_size[i]*sizeof(tile_struct));
  139.     }
  140.  
  141.     max_list_size[16] = 65536;
  142.     if ((tile_list[16]=(tile_struct *)malloc(max_list_size[16]*sizeof(tile_struct))) == 0)
  143.     {
  144.         for (i=15; i>=0; i--)
  145.             free(tile_list[i]);
  146.         for (i=3; i>=0; i--)
  147.             free(bg_list[i]);
  148.         free(paletteram);
  149.         free(toaplan1_videoram3);
  150.         return 1;
  151.     }
  152.     memset(tile_list[16],0,max_list_size[16]*sizeof(tile_struct));
  153.  
  154.     num_tiles = (Machine->drv->screen_width/8+1)*(Machine->drv->screen_height/8) ;
  155.  
  156.     video_ofs = video_ofs3 = 0;
  157.  
  158.     return 0;
  159. }
  160.  
  161. void rallybik_vh_stop(void)
  162. {
  163.     int i ;
  164.  
  165.     for (i=16; i>=0; i--)
  166.     {
  167.         free(tile_list[i]);
  168.         logerror("max_list_size[%d]=%08x\n",i,max_list_size[i]);
  169.     }
  170.  
  171.     for (i=3; i>=0; i--)
  172.         free(bg_list[i]);
  173.  
  174.     free (paletteram);
  175.     free(toaplan1_videoram3);
  176. }
  177.  
  178. int toaplan1_vh_start(void)
  179. {
  180.     tmpbitmap1 = osd_new_bitmap(
  181.                     Machine->drv->screen_width,
  182.                     Machine->drv->screen_height,
  183.                     Machine->scrbitmap->depth);
  184.  
  185.     tmpbitmap2 = osd_new_bitmap(
  186.                     Machine->drv->screen_width,
  187.                     Machine->drv->screen_height,
  188.                     Machine->scrbitmap->depth);
  189.  
  190.     tmpbitmap3 = osd_new_bitmap(
  191.                     Machine->drv->screen_width,
  192.                     Machine->drv->screen_height,
  193.                     Machine->scrbitmap->depth);
  194.  
  195.  
  196.     if ((toaplan1_videoram1 = calloc(VIDEORAM1_SIZE, 1)) == 0)
  197.     {
  198.         return 1;
  199.     }
  200.     if ((toaplan1_buffered_videoram1 = calloc(VIDEORAM1_SIZE, 1)) == 0)
  201.     {
  202.         free(toaplan1_videoram1);
  203.         return 1;
  204.     }
  205.     if ((toaplan1_videoram2 = calloc(VIDEORAM2_SIZE, 1)) == 0)
  206.     {
  207.         free(toaplan1_buffered_videoram1);
  208.         free(toaplan1_videoram1);
  209.         return 1;
  210.     }
  211.     if ((toaplan1_buffered_videoram2 = calloc(VIDEORAM2_SIZE, 1)) == 0)
  212.     {
  213.         free(toaplan1_videoram2);
  214.         free(toaplan1_buffered_videoram1);
  215.         free(toaplan1_videoram1);
  216.         return 1;
  217.     }
  218.  
  219.     /* Also include all allocated stuff in Rally Bike startup */
  220.     return rallybik_vh_start();
  221. }
  222.  
  223. void toaplan1_vh_stop(void)
  224. {
  225.     rallybik_vh_stop();
  226.  
  227.     free(toaplan1_buffered_videoram2);
  228.     free(toaplan1_videoram2);
  229.     free(toaplan1_buffered_videoram1);
  230.     free(toaplan1_videoram1);
  231.     osd_free_bitmap(tmpbitmap3);
  232.     osd_free_bitmap(tmpbitmap2);
  233.     osd_free_bitmap(tmpbitmap1);
  234. }
  235.  
  236.  
  237.  
  238.  
  239. READ_HANDLER( toaplan1_vblank_r )
  240. {
  241.     return vblank ^= 1;
  242. }
  243.  
  244. WRITE_HANDLER( toaplan1_flipscreen_w )
  245. {
  246.     toaplan1_flipscreen = data; /* 8000 flip, 0000 dont */
  247. }
  248.  
  249. READ_HANDLER( video_ofs_r )
  250. {
  251.     return video_ofs ;
  252. }
  253.  
  254. WRITE_HANDLER( video_ofs_w )
  255. {
  256.     video_ofs = data ;
  257. }
  258.  
  259. /* tile palette */
  260. READ_HANDLER( toaplan1_colorram1_r )
  261. {
  262.     return READ_WORD (&toaplan1_colorram1[offset]);
  263. }
  264.  
  265. WRITE_HANDLER( toaplan1_colorram1_w )
  266. {
  267.     WRITE_WORD (&toaplan1_colorram1[offset], data);
  268.     paletteram_xBBBBBGGGGGRRRRR_word_w(offset,data);
  269. }
  270.  
  271. /* sprite palette */
  272. READ_HANDLER( toaplan1_colorram2_r )
  273. {
  274.     return READ_WORD (&toaplan1_colorram2[offset]);
  275. }
  276.  
  277. WRITE_HANDLER( toaplan1_colorram2_w )
  278. {
  279.     WRITE_WORD (&toaplan1_colorram2[offset], data);
  280.     paletteram_xBBBBBGGGGGRRRRR_word_w(offset+colorram1_size,data);
  281. }
  282.  
  283. READ_HANDLER( toaplan1_videoram1_r )
  284. {
  285.     return READ_WORD (&toaplan1_videoram1[2*(video_ofs & (VIDEORAM1_SIZE-1))]);
  286. }
  287.  
  288. WRITE_HANDLER( toaplan1_videoram1_w )
  289. {
  290.     int oldword = READ_WORD (&toaplan1_videoram1[2*video_ofs & (VIDEORAM1_SIZE-1)]);
  291.     int newword = COMBINE_WORD (oldword, data);
  292.  
  293. #ifdef DEBUG
  294.     if (2*video_ofs >= VIDEORAM1_SIZE)
  295.     {
  296.         logerror("videoram1_w, %08x\n", 2*video_ofs);
  297.         return;
  298.     }
  299. #endif
  300.  
  301.     WRITE_WORD (&toaplan1_videoram1[2*video_ofs & (VIDEORAM1_SIZE-1)],newword);
  302.     video_ofs++;
  303. }
  304.  
  305. READ_HANDLER( toaplan1_videoram2_r )
  306. {
  307.     return READ_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)]);
  308. }
  309.  
  310. WRITE_HANDLER( toaplan1_videoram2_w )
  311. {
  312.     int oldword = READ_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)]);
  313.     int newword = COMBINE_WORD (oldword, data);
  314.  
  315. #ifdef DEBUG
  316.     if (2*video_ofs >= VIDEORAM2_SIZE)
  317.     {
  318.         logerror("videoram2_w, %08x\n", 2*video_ofs);
  319.         return;
  320.     }
  321. #endif
  322.  
  323.     WRITE_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)],newword);
  324.     video_ofs++;
  325. }
  326.  
  327. READ_HANDLER( video_ofs3_r )
  328. {
  329.     return video_ofs3;
  330. }
  331.  
  332. WRITE_HANDLER( video_ofs3_w )
  333. {
  334.     video_ofs3 = data ;
  335. }
  336.  
  337. READ_HANDLER( rallybik_videoram3_r )
  338. {
  339.     int rb_tmp_vid;
  340.  
  341.     rb_tmp_vid = READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
  342.  
  343.     if (offset == 0)
  344.     {
  345.         rb_tmp_vid |= ((rb_tmp_vid & 0xf000) >> 4);
  346.         rb_tmp_vid |= ((rb_tmp_vid & 0x0030) << 2);
  347.     }
  348.     return rb_tmp_vid;
  349. }
  350.  
  351. READ_HANDLER( toaplan1_videoram3_r )
  352. {
  353.     return READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
  354. }
  355.  
  356. WRITE_HANDLER( toaplan1_videoram3_w )
  357. {
  358.     int oldword = READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
  359.     int newword = COMBINE_WORD (oldword, data);
  360.  
  361. #ifdef DEBUG
  362.     if ((video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset >= VIDEORAM3_SIZE*4)
  363.     {
  364.         logerror("videoram3_w, %08x\n", 2*video_ofs3);
  365.         return;
  366.     }
  367. #endif
  368.  
  369.     WRITE_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset],newword);
  370.     if ( offset == 2 ) video_ofs3++;
  371. }
  372.  
  373. READ_HANDLER( scrollregs_r )
  374. {
  375.     return scrollregs[offset>>1];
  376. }
  377.  
  378. WRITE_HANDLER( scrollregs_w )
  379. {
  380.     scrollregs[offset>>1] = data ;
  381. }
  382.  
  383. WRITE_HANDLER( offsetregs_w )
  384. {
  385.     if ( offset == 0 )
  386.         tiles_offsetx = data ;
  387.     else
  388.         tiles_offsety = data ;
  389. }
  390.  
  391. WRITE_HANDLER( layers_offset_w )
  392. {
  393.     switch (offset)
  394.     {
  395. /*        case 0:
  396.             layers_offset[0] = (data&0xff) - 0xdb ;
  397.             break ;
  398.         case 2:
  399.             layers_offset[1] = (data&0xff) - 0x14 ;
  400.             break ;
  401.         case 4:
  402.             layers_offset[2] = (data&0xff) - 0x85 ;
  403.             break ;
  404.         case 6:
  405.             layers_offset[3] = (data&0xff) - 0x07 ;
  406.             break ;
  407. */
  408.         case 0:
  409.             layers_offset[0] = data;
  410.             break ;
  411.         case 2:
  412.             layers_offset[1] = data;
  413.             break ;
  414.         case 4:
  415.             layers_offset[2] = data;
  416.             break ;
  417.         case 6:
  418.             layers_offset[3] = data;
  419.             break ;
  420.     }
  421.  
  422.     logerror("layers_offset[0]:%08x\n",layers_offset[0]);
  423.     logerror("layers_offset[1]:%08x\n",layers_offset[1]);
  424.     logerror("layers_offset[2]:%08x\n",layers_offset[2]);
  425.     logerror("layers_offset[3]:%08x\n",layers_offset[3]);
  426.  
  427. }
  428.  
  429. /***************************************************************************
  430.  
  431.   Draw the game screen in the given osd_bitmap.
  432.  
  433. ***************************************************************************/
  434.  
  435.  
  436. static void toaplan1_update_palette (void)
  437. {
  438.     int i;
  439.     int priority;
  440.     int color;
  441.     unsigned short palette_map[64*2];
  442.  
  443.     memset (palette_map, 0, sizeof (palette_map));
  444.  
  445.     /* extract color info from priority layers in order */
  446.     for (priority = 0; priority < 17; priority++ )
  447.     {
  448.         tile_struct *tinfo;
  449.  
  450.         tinfo = (tile_struct *)&(tile_list[priority][0]);
  451.         /* draw only tiles in list */
  452.         for ( i = 0; i < tile_count[priority]; i++ )
  453.         {
  454.             int bank;
  455.  
  456.             bank  = (tinfo->color >> 7) & 1;
  457.             color = (tinfo->color & 0x3f);
  458.             palette_map[color + bank*64] |= Machine->gfx[bank]->pen_usage[tinfo->tile_num & (Machine->gfx[bank]->total_elements-1)];
  459.  
  460.             tinfo++;
  461.         }
  462.     }
  463.  
  464.     /* Tell MAME about the color usage */
  465.     for (i = 0; i < 64*2; i++)
  466.     {
  467.         int usage = palette_map[i];
  468.         int j;
  469.  
  470.         if (usage)
  471.         {
  472.             palette_used_colors[i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  473.             for (j = 0; j < 16; j++)
  474.             {
  475.                 if (usage & (1 << j))
  476.                     palette_used_colors[i * 16 + j] = PALETTE_COLOR_USED;
  477.                 else
  478.                     palette_used_colors[i * 16 + j] = PALETTE_COLOR_UNUSED;
  479.             }
  480.         }
  481.         else
  482.             memset(&palette_used_colors[i * 16],PALETTE_COLOR_UNUSED,16);
  483.     }
  484.  
  485.     palette_recalc ();
  486. }
  487.  
  488.  
  489.  
  490. static int     layer_scrollx[4];
  491. static int     layer_scrolly[4];
  492.  
  493. static void toaplan1_find_tiles(int xoffs,int yoffs)
  494. {
  495.     int priority;
  496.     int layer;
  497.     tile_struct *tinfo;
  498.     unsigned char *t_info;
  499.  
  500.     if(toaplan1_flipscreen){
  501.         layer_scrollx[0] = ((scrollregs[0]) >> 7) + (523 - xoffs);
  502.         layer_scrollx[1] = ((scrollregs[2]) >> 7) + (525 - xoffs);
  503.         layer_scrollx[2] = ((scrollregs[4]) >> 7) + (527 - xoffs);
  504.         layer_scrollx[3] = ((scrollregs[6]) >> 7) + (529 - xoffs);
  505.  
  506.         layer_scrolly[0] = ((scrollregs[1]) >> 7) +    (256 - yoffs);
  507.         layer_scrolly[1] = ((scrollregs[3]) >> 7) + (256 - yoffs);
  508.         layer_scrolly[2] = ((scrollregs[5]) >> 7) + (256 - yoffs);
  509.         layer_scrolly[3] = ((scrollregs[7]) >> 7) + (256 - yoffs);
  510.     }else{
  511.         layer_scrollx[0] = ((scrollregs[0]) >> 7) +(495 - xoffs + 6);
  512.         layer_scrollx[1] = ((scrollregs[2]) >> 7) +(495 - xoffs + 4);
  513.         layer_scrollx[2] = ((scrollregs[4]) >> 7) +(495 - xoffs + 2);
  514.         layer_scrollx[3] = ((scrollregs[6]) >> 7) +(495 - xoffs);
  515.  
  516.         layer_scrolly[0] = ((scrollregs[1]) >> 7) +    (0x101 - yoffs);
  517.         layer_scrolly[1] = ((scrollregs[3]) >> 7) + (0x101 - yoffs);
  518.         layer_scrolly[2] = ((scrollregs[5]) >> 7) + (0x101 - yoffs);
  519.         layer_scrolly[3] = ((scrollregs[7]) >> 7) + (0x101 - yoffs);
  520.     }
  521.  
  522.     for ( layer = 3 ; layer >= 0 ; layer-- )
  523.     {
  524.         int scrolly,scrollx,offsetx,offsety;
  525.         int sx,sy,tattr;
  526.         int i;
  527.  
  528.         t_info = (toaplan1_videoram3+layer * VIDEORAM3_SIZE);
  529.         scrollx = layer_scrollx[layer];
  530.         offsetx = scrollx / 8 ;
  531.         scrolly = layer_scrolly[layer];
  532.         offsety = scrolly / 8 ;
  533.  
  534.         for ( sy = 0 ; sy < 32 ; sy++ )
  535.         {
  536.             for ( sx = 0 ; sx <= 40 ; sx++ )
  537.             {
  538.                 i = ((sy+offsety)&0x3f)*256 + ((sx+offsetx)&0x3f)*4 ;
  539.                 tattr = READ_WORD(&t_info[i]);
  540.                 priority = (tattr >> 12);
  541.  
  542.                 tinfo = (tile_struct *)&(bg_list[layer][sy*41+sx]) ;
  543.                 tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
  544.                 tinfo->priority = priority ;
  545.                 tinfo->color = tattr & 0x3f ;
  546.                 tinfo->xpos = (sx*8)-(scrollx&0x7) ;
  547.                 tinfo->ypos = (sy*8)-(scrolly&0x7) ;
  548.  
  549.                 if ( (priority) || (layer == 0) )    /* if priority 0 draw layer 0 only */
  550.                 {
  551.  
  552.                     tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
  553.                     tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
  554.                     if ( (tinfo->tile_num & 0x8000) == 0 )
  555.                     {
  556.                         tinfo->priority = priority ;
  557.                         tinfo->color = tattr & 0x3f ;
  558.                         tinfo->color |= layer<<8;
  559.                         tinfo->xpos = (sx*8)-(scrollx&0x7) ;
  560.                         tinfo->ypos = (sy*8)-(scrolly&0x7) ;
  561.                         tile_count[priority]++ ;
  562.                         if(tile_count[priority]==max_list_size[priority])
  563.                         {
  564.                             /*reallocate tile_list[priority] to larger size */
  565.                             temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
  566.                             memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
  567.                             max_list_size[priority]+=512;
  568.                             free(tile_list[priority]);
  569.                             tile_list[priority] = temp_list ;
  570.                         }
  571.                     }
  572.                 }
  573.             }
  574.         }
  575.     }
  576.     for ( layer = 3 ; layer >= 0 ; layer-- )
  577.     {
  578.         layer_scrollx[layer] &= 0x7;
  579.         layer_scrolly[layer] &= 0x7;
  580.     }
  581. }
  582.  
  583. static void rallybik_find_tiles(void)
  584. {
  585.     int priority;
  586.     int layer;
  587.     tile_struct *tinfo;
  588.     unsigned char *t_info;
  589.  
  590.     for ( priority = 0 ; priority < 16 ; priority++ )
  591.     {
  592.         tile_count[priority]=0;
  593.     }
  594.  
  595.     for ( layer = 3 ; layer >= 0 ; layer-- )
  596.     {
  597.         int scrolly,scrollx,offsetx,offsety;
  598.         int sx,sy,tattr;
  599.         int i;
  600.  
  601.         t_info = (toaplan1_videoram3+layer * VIDEORAM3_SIZE);
  602.         scrollx = scrollregs[layer*2];
  603.         scrolly = scrollregs[(layer*2)+1];
  604.  
  605.         scrollx >>= 7 ;
  606.         scrollx += 43 ;
  607.         if ( layer == 0 ) scrollx += 2 ;
  608.         if ( layer == 2 ) scrollx -= 2 ;
  609.         if ( layer == 3 ) scrollx -= 4 ;
  610.         offsetx = scrollx / 8 ;
  611.  
  612.         scrolly >>= 7 ;
  613.         scrolly += 21 ;
  614.         offsety = scrolly / 8 ;
  615.  
  616.         for ( sy = 0 ; sy < 32 ; sy++ )
  617.         {
  618.             for ( sx = 0 ; sx <= 40 ; sx++ )
  619.             {
  620.                 i = ((sy+offsety)&0x3f)*256 + ((sx+offsetx)&0x3f)*4 ;
  621.                 tattr = READ_WORD(&t_info[i]);
  622.                 priority = tattr >> 12 ;
  623.                 if ( (priority) || (layer == 0) )    /* if priority 0 draw layer 0 only */
  624.                 {
  625.                     tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
  626.                     tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
  627.  
  628.                     if ( !((priority) && (tinfo->tile_num & 0x8000)) )
  629.                     {
  630.                         tinfo->tile_num &= 0x3fff ;
  631.                         tinfo->color = tattr & 0x3f ;
  632.                         tinfo->xpos = (sx*8)-(scrollx&0x7) ;
  633.                         tinfo->ypos = (sy*8)-(scrolly&0x7) ;
  634.                         tile_count[priority]++ ;
  635.                         if(tile_count[priority]==max_list_size[priority])
  636.                         {
  637.                             /*reallocate tile_list[priority] to larger size */
  638.                             temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
  639.                             memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
  640.                             max_list_size[priority]+=512;
  641.                             free(tile_list[priority]);
  642.                             tile_list[priority] = temp_list ;
  643.                         }
  644.                     }
  645.                 }
  646.             }
  647.         }
  648.     }
  649. }
  650.  
  651. unsigned long toaplan_sp_ram_dump = 0;
  652.  
  653. static void toaplan1_find_sprites (void)
  654. {
  655.     int priority;
  656.     int sprite;
  657.     unsigned char *s_info,*s_size;
  658.  
  659.  
  660.     for ( priority = 0 ; priority < 17 ; priority++ )
  661.     {
  662.         tile_count[priority]=0;
  663.     }
  664.  
  665.  
  666. #if 0        // sp ram dump start
  667.     s_size = (toaplan1_buffered_videoram2);        /* sprite block size */
  668.     s_info = (toaplan1_buffered_videoram1);        /* start of sprite ram */
  669.     if( (toaplan_sp_ram_dump == 0)
  670.      && (keyboard_pressed(KEYCODE_N)) )
  671.     {
  672.         toaplan_sp_ram_dump = 1;
  673.         for ( sprite = 0 ; sprite < 256 ; sprite++ )
  674.         {
  675.             int tattr,tchar;
  676.             tchar = READ_WORD (&s_info[0]) & 0xffff;
  677.             tattr = READ_WORD (&s_info[2]);
  678.             logerror("%08x: %04x %04x\n", sprite, tattr, tchar);
  679.             s_info += 8 ;
  680.         }
  681.     }
  682. #endif        // end
  683.  
  684.     s_size = (toaplan1_buffered_videoram2);        /* sprite block size */
  685.     s_info = (toaplan1_buffered_videoram1);        /* start of sprite ram */
  686.  
  687.     for ( sprite = 0 ; sprite < 256 ; sprite++ )
  688.     {
  689.         int tattr,tchar;
  690.  
  691.         tchar = READ_WORD (&s_info[0]) & 0xffff;
  692.         tattr = READ_WORD (&s_info[2]);
  693.  
  694.         if ( (tattr & 0xf000) && ((tchar & 0x8000) == 0) )
  695.         {
  696.             int sx,sy,dx,dy,s_sizex,s_sizey;
  697.             int sprite_size_ptr;
  698.  
  699.             sx=READ_WORD(&s_info[4]);
  700.             sx >>= 7 ;
  701.             if ( sx > 416 ) sx -= 512 ;
  702.  
  703.             sy=READ_WORD(&s_info[6]);
  704.             sy >>= 7 ;
  705.             if ( sy > 416 ) sy -= 512 ;
  706.  
  707.             priority = (tattr >> 12);
  708.  
  709.             sprite_size_ptr = (tattr>>6)&0x3f ;
  710.             s_sizey = (READ_WORD(&s_size[2*sprite_size_ptr])>>4)&0xf ;
  711.             s_sizex = (READ_WORD(&s_size[2*sprite_size_ptr]))&0xf ;
  712.  
  713.             for ( dy = s_sizey ; dy > 0 ; dy-- )
  714.             for ( dx = s_sizex; dx > 0 ; dx-- )
  715.             {
  716.                 tile_struct *tinfo;
  717.  
  718.                 tinfo = (tile_struct *)&(tile_list[16][tile_count[16]]) ;
  719.                 tinfo->priority = priority;
  720.                 tinfo->tile_num = tchar;
  721.                 tinfo->color = 0x80 | (tattr & 0x3f) ;
  722.                 tinfo->xpos = sx-dx*8+s_sizex*8 ;
  723.                 tinfo->ypos = sy-dy*8+s_sizey*8 ;
  724.                 tile_count[16]++ ;
  725.                 if(tile_count[16]==max_list_size[16])
  726.                 {
  727.                     /*reallocate tile_list[priority] to larger size */
  728.                     temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[16]+512)) ;
  729.                     memcpy(temp_list,tile_list[16],sizeof(tile_struct)*max_list_size[16]);
  730.                     max_list_size[16]+=512;
  731.                     free(tile_list[16]);
  732.                     tile_list[16] = temp_list ;
  733.                 }
  734.                 tchar++;
  735.             }
  736.         }
  737.         s_info += 8 ;
  738.     }
  739. }
  740.  
  741. static void rallybik_find_sprites (void)
  742. {
  743.     int offs;
  744.     int tattr;
  745.     int sx,sy,tchar;
  746.     int priority;
  747.     tile_struct *tinfo;
  748.  
  749.     for (offs = 0;offs < spriteram_size;offs += 8)
  750.     {
  751.         tattr = READ_WORD(&buffered_spriteram[offs+2]);
  752.         if ( tattr )    /* no need to render hidden sprites */
  753.         {
  754.             sx=READ_WORD(&buffered_spriteram[offs+4]);
  755.             sx >>= 7 ;
  756.             sx &= 0x1ff ;
  757.             if ( sx > 416 ) sx -= 512 ;
  758.  
  759.             sy=READ_WORD(&buffered_spriteram[offs+6]);
  760.             sy >>= 7 ;
  761.             sy &= 0x1ff ;
  762.             if ( sy > 416 ) sy -= 512 ;
  763.  
  764.             priority = (tattr>>8) & 0xc ;
  765.             tchar = READ_WORD(&buffered_spriteram[offs+0]);
  766.             tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
  767.             tinfo->tile_num = tchar & 0x7ff ;
  768.             tinfo->color = 0x80 | (tattr&0x3f) ;
  769.             tinfo->color |= (tattr & 0x0100) ;
  770.             tinfo->color |= (tattr & 0x0200) ;
  771.             if (tinfo->color & 0x0100) sx -= 15;
  772.  
  773.             tinfo->xpos = sx-31 ;
  774.             tinfo->ypos = sy-16 ;
  775.             tile_count[priority]++ ;
  776.             if(tile_count[priority]==max_list_size[priority])
  777.             {
  778.                 /*reallocate tile_list[priority] to larger size */
  779.                 temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
  780.                 memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
  781.                 max_list_size[priority]+=512;
  782.                 free(tile_list[priority]);
  783.                 tile_list[priority] = temp_list ;
  784.             }
  785.         }  // if tattr
  786.     } // for sprite
  787. }
  788.  
  789.  
  790. void toaplan1_fillbgmask(struct osd_bitmap *dest_bmp, struct osd_bitmap *source_bmp,
  791.  const struct rectangle *clip,int transparent_color)
  792. {
  793.     struct rectangle myclip;
  794.     int sx=0;
  795.     int sy=0;
  796.  
  797.     if (Machine->orientation & ORIENTATION_SWAP_XY)
  798.     {
  799.         int temp;
  800.  
  801.         /* clip and myclip might be the same, so we need a temporary storage */
  802.         temp = clip->min_x;
  803.         myclip.min_x = clip->min_y;
  804.         myclip.min_y = temp;
  805.         temp = clip->max_x;
  806.         myclip.max_x = clip->max_y;
  807.         myclip.max_y = temp;
  808.         clip = &myclip;
  809.     }
  810.     if (Machine->orientation & ORIENTATION_FLIP_X)
  811.     {
  812.         int temp;
  813.  
  814.         sx = -sx;
  815.  
  816.         /* clip and myclip might be the same, so we need a temporary storage */
  817.         temp = clip->min_x;
  818.         myclip.min_x = dest_bmp->width-1 - clip->max_x;
  819.         myclip.max_x = dest_bmp->width-1 - temp;
  820.         myclip.min_y = clip->min_y;
  821.         myclip.max_y = clip->max_y;
  822.         clip = &myclip;
  823.     }
  824.     if (Machine->orientation & ORIENTATION_FLIP_Y)
  825.     {
  826.         int temp;
  827.  
  828.         sy = -sy;
  829.  
  830.         myclip.min_x = clip->min_x;
  831.         myclip.max_x = clip->max_x;
  832.         /* clip and myclip might be the same, so we need a temporary storage */
  833.         temp = clip->min_y;
  834.         myclip.min_y = dest_bmp->height-1 - clip->max_y;
  835.         myclip.max_y = dest_bmp->height-1 - temp;
  836.         clip = &myclip;
  837.     }
  838.  
  839.     if (dest_bmp->depth != 16)
  840.     {
  841.         int ex = sx+source_bmp->width;
  842.         int ey = sy+source_bmp->height;
  843.  
  844.         if( sx < clip->min_x)
  845.         { /* clip left */
  846.             sx = clip->min_x;
  847.         }
  848.         if( sy < clip->min_y )
  849.         { /* clip top */
  850.             sy = clip->min_y;
  851.         }
  852.         if( ex > clip->max_x+1 )
  853.         { /* clip right */
  854.             ex = clip->max_x + 1;
  855.         }
  856.         if( ey > clip->max_y+1 )
  857.         { /* clip bottom */
  858.             ey = clip->max_y + 1;
  859.         }
  860.  
  861.         if( ex>sx )
  862.         { /* skip if inner loop doesn't draw anything */
  863.             int y;
  864.             for( y=sy; y<ey; y++ )
  865.             {
  866.                 unsigned char *dest = dest_bmp->line[y];
  867.                 unsigned char *source = source_bmp->line[y];
  868.                 int x;
  869.  
  870.                 for( x=sx; x<ex; x++ )
  871.                 {
  872.                     int c = source[x];
  873.                     if( c != transparent_color )
  874.                         dest[x] = transparent_color;
  875.                 }
  876.             }
  877.         }
  878.     }
  879.  
  880.     else
  881.     {
  882.         int ex = sx+source_bmp->width;
  883.         int ey = sy+source_bmp->height;
  884.  
  885.         if( sx < clip->min_x)
  886.         { /* clip left */
  887.             sx = clip->min_x;
  888.         }
  889.         if( sy < clip->min_y )
  890.         { /* clip top */
  891.             sy = clip->min_y;
  892.         }
  893.         if( ex > clip->max_x+1 )
  894.         { /* clip right */
  895.             ex = clip->max_x + 1;
  896.         }
  897.         if( ey > clip->max_y+1 )
  898.         { /* clip bottom */
  899.             ey = clip->max_y + 1;
  900.         }
  901.  
  902.         if( ex>sx )
  903.         { /* skip if inner loop doesn't draw anything */
  904.             int y;
  905.  
  906.             for( y=sy; y<ey; y++ )
  907.             {
  908.                 unsigned short *dest = (unsigned short *)dest_bmp->line[y];
  909.                 unsigned char *source = source_bmp->line[y];
  910.                 int x;
  911.  
  912.                 for( x=sx; x<ex; x++ )
  913.                 {
  914.                     int c = source[x];
  915.                     if( c != transparent_color )
  916.                         dest[x] = transparent_color;
  917.                 }
  918.             }
  919.         }
  920.     }
  921. }
  922.  
  923.  
  924. //#define BGDBG
  925. #ifdef BGDBG
  926. int    toaplan_dbg_priority = 0;
  927. #endif
  928.  
  929.  
  930. static void toaplan1_render (struct osd_bitmap *bitmap)
  931. {
  932.     int i,j;
  933.     int priority,pen;
  934.     int    flip;
  935.     tile_struct *tinfo;
  936.     tile_struct *tinfo2;
  937.     struct rectangle sp_rect;
  938.  
  939.     fillbitmap (bitmap, palette_transparent_pen, &Machine->drv->visible_area);
  940.  
  941. #ifdef BGDBG
  942.  
  943. if (keyboard_pressed(KEYCODE_Q)) { toaplan_dbg_priority = 0; }
  944. if (keyboard_pressed(KEYCODE_W)) { toaplan_dbg_priority = 1; }
  945. if (keyboard_pressed(KEYCODE_E)) { toaplan_dbg_priority = 2; }
  946. if (keyboard_pressed(KEYCODE_R)) { toaplan_dbg_priority = 3; }
  947. if (keyboard_pressed(KEYCODE_T)) { toaplan_dbg_priority = 4; }
  948. if (keyboard_pressed(KEYCODE_Y)) { toaplan_dbg_priority = 5; }
  949. if (keyboard_pressed(KEYCODE_U)) { toaplan_dbg_priority = 6; }
  950. if (keyboard_pressed(KEYCODE_I)) { toaplan_dbg_priority = 7; }
  951. if (keyboard_pressed(KEYCODE_A)) { toaplan_dbg_priority = 8; }
  952. if (keyboard_pressed(KEYCODE_S)) { toaplan_dbg_priority = 9; }
  953. if (keyboard_pressed(KEYCODE_D)) { toaplan_dbg_priority = 10; }
  954. if (keyboard_pressed(KEYCODE_F)) { toaplan_dbg_priority = 11; }
  955. if (keyboard_pressed(KEYCODE_G)) { toaplan_dbg_priority = 12; }
  956. if (keyboard_pressed(KEYCODE_H)) { toaplan_dbg_priority = 13; }
  957. if (keyboard_pressed(KEYCODE_J)) { toaplan_dbg_priority = 14; }
  958. if (keyboard_pressed(KEYCODE_K)) { toaplan_dbg_priority = 15; }
  959.  
  960. if( toaplan_dbg_priority != 0 ){
  961.  
  962.     priority = toaplan_dbg_priority;
  963.     {
  964.         tinfo = (tile_struct *)&(tile_list[priority][0]) ;
  965.         /* hack to fix black blobs in Demon's World sky */
  966.         pen = TRANSPARENCY_NONE ;
  967.         for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
  968.         {
  969.             /* hack to fix blue blobs in Zero Wing attract mode */
  970. //            if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
  971. //                pen = TRANSPARENCY_PEN ;
  972.             drawgfx(bitmap,Machine->gfx[0],
  973.                 tinfo->tile_num,
  974.                 (tinfo->color&0x3f),
  975.                 0,0,                        /* flipx,flipy */
  976.                 tinfo->xpos,tinfo->ypos,
  977.                 &Machine->drv->visible_area,pen,0);
  978.             tinfo++ ;
  979.         }
  980.     }
  981.  
  982. }else{
  983.  
  984. #endif
  985.  
  986. //    if(toaplan1_flipscreen)
  987. //        flip = 1;
  988. //    else
  989.         flip = 0;
  990. //
  991.     priority = 0;
  992.     while ( priority < 16 )            /* draw priority layers in order */
  993.     {
  994.         int    layer;
  995.  
  996.         tinfo = (tile_struct *)&(tile_list[priority][0]) ;
  997.         layer = (tinfo->color >> 8);
  998.         if ( (layer < 3) && (priority < 2))
  999.             pen = TRANSPARENCY_NONE ;
  1000.         else
  1001.             pen = TRANSPARENCY_PEN ;
  1002.  
  1003.         for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
  1004.         {
  1005.             int    xpos,ypos;
  1006.  
  1007.             /* hack to fix blue blobs in Zero Wing attract mode */
  1008. //            if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
  1009. //                pen = TRANSPARENCY_PEN ;
  1010.  
  1011. //            if ( flip ){
  1012. //                xpos = tinfo->xpos;
  1013. //                ypos = tinfo->ypos;
  1014. //            }
  1015. //            else{
  1016.                 xpos = tinfo->xpos;
  1017.                 ypos = tinfo->ypos;
  1018. //            }
  1019.  
  1020.             drawgfx(bitmap,Machine->gfx[0],
  1021.                 tinfo->tile_num,
  1022.                 (tinfo->color&0x3f),
  1023.                 flip,flip,                            /* flipx,flipy */
  1024.                 tinfo->xpos,tinfo->ypos,
  1025.                 &Machine->drv->visible_area,pen,0);
  1026.             tinfo++ ;
  1027.         }
  1028.         priority++;
  1029.     }
  1030.  
  1031.     tinfo2 = (tile_struct *)&(tile_list[16][0]) ;
  1032.     for ( i = 0; i < tile_count[16]; i++ )    /* draw sprite No. in order */
  1033.     {
  1034.         int    flipx,flipy;
  1035.  
  1036.         sp_rect.min_x = tinfo2->xpos;
  1037.         sp_rect.min_y = tinfo2->ypos;
  1038.         sp_rect.max_x = tinfo2->xpos + 7;
  1039.         sp_rect.max_y = tinfo2->ypos + 7;
  1040.  
  1041.         fillbitmap (tmpbitmap2, palette_transparent_pen, &sp_rect);
  1042.  
  1043.         flipx = (tinfo2->color & 0x0100);
  1044.         flipy = (tinfo2->color & 0x0200);
  1045. //        if(toaplan1_flipscreen){
  1046. //            flipx = !flipx;
  1047. //            flipy = !flipy;
  1048. //        }
  1049.         drawgfx(tmpbitmap2,Machine->gfx[1],
  1050.             tinfo2->tile_num,
  1051.             (tinfo2->color&0x3f),             /* bit 7 not for colour */
  1052.             flipx,flipy,                    /* flipx,flipy */
  1053.             tinfo2->xpos,tinfo2->ypos,
  1054.             &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  1055.  
  1056.         priority = tinfo2->priority;
  1057.         {
  1058.         int ix0,ix1,ix2,ix3;
  1059.         int dirty;
  1060.  
  1061.         dirty = 0;
  1062.         fillbitmap (tmpbitmap3, palette_transparent_pen, &sp_rect);
  1063.         for ( j = 0 ; j < 4 ; j++ )
  1064.         {
  1065.             int x,y;
  1066.  
  1067.             y = tinfo2->ypos+layer_scrolly[j];
  1068.             x = tinfo2->xpos+layer_scrollx[j];
  1069.             ix0 = ( y   /8) * 41 +  x   /8;
  1070.             ix1 = ( y   /8) * 41 + (x+7)/8;
  1071.             ix2 = ((y+7)/8) * 41 +  x   /8;
  1072.             ix3 = ((y+7)/8) * 41 + (x+7)/8;
  1073.  
  1074.             if(    (ix0 >= 0) && (ix0 < 32*41) ){
  1075.                 tinfo = (tile_struct *)&(bg_list[j][ix0]) ;
  1076.                 if( (tinfo->priority >= tinfo2->priority) ){
  1077.                     drawgfx(tmpbitmap3,Machine->gfx[0],
  1078. //                    drawgfx(tmpbitmap2,Machine->gfx[0],
  1079.                         tinfo->tile_num,
  1080.                         (tinfo->color&0x3f),
  1081.                         flip,flip,
  1082.                         tinfo->xpos,tinfo->ypos,
  1083.                         &sp_rect,TRANSPARENCY_PEN,0);
  1084.                     dirty=1;
  1085.                 }
  1086.             }
  1087.             if(    (ix1 >= 0) && (ix1 < 32*41) ){
  1088.                 tinfo = (tile_struct *)&(bg_list[j][ix1]) ;
  1089. //                tinfo++;
  1090.                 if( (ix0 != ix1)
  1091.                  && (tinfo->priority >= tinfo2->priority) ){
  1092.                     drawgfx(tmpbitmap3,Machine->gfx[0],
  1093. //                    drawgfx(tmpbitmap2,Machine->gfx[0],
  1094.                         tinfo->tile_num,
  1095.                         (tinfo->color&0x3f),
  1096.                         flip,flip,
  1097.                         tinfo->xpos,tinfo->ypos,
  1098.                         &sp_rect,TRANSPARENCY_PEN,0);
  1099.                     dirty=1;
  1100.                 }
  1101.             }
  1102.             if(    (ix2 >= 0) && (ix2 < 32*41) ){
  1103.                 tinfo = (tile_struct *)&(bg_list[j][ix2]) ;
  1104. //                tinfo += 40;
  1105.                 if( (ix0 != ix2)
  1106.                  && (tinfo->priority >= tinfo2->priority) ){
  1107.                     drawgfx(tmpbitmap3,Machine->gfx[0],
  1108. //                    drawgfx(tmpbitmap2,Machine->gfx[0],
  1109.                         tinfo->tile_num,
  1110.                         (tinfo->color&0x3f),
  1111.                         flip,flip,
  1112.                         tinfo->xpos,tinfo->ypos,
  1113.                         &sp_rect,TRANSPARENCY_PEN,0);
  1114.                     dirty=1;
  1115.                 }
  1116.             }
  1117.             if(    (ix3 >= 0) && (ix3 < 32*41) ){
  1118.                 tinfo = (tile_struct *)&(bg_list[j][ix3]) ;
  1119. //                tinfo++;
  1120.                 if( (ix0 != ix3) && (ix1 != ix3) && (ix2 != ix3)
  1121.                  && (tinfo->priority >= tinfo2->priority) ){
  1122.                     drawgfx(tmpbitmap3,Machine->gfx[0],
  1123. //                    drawgfx(tmpbitmap2,Machine->gfx[0],
  1124.                         tinfo->tile_num,
  1125.                         (tinfo->color&0x3f),
  1126.                         flip,flip,
  1127.                         tinfo->xpos,tinfo->ypos,
  1128.                         &sp_rect,TRANSPARENCY_PEN,0);
  1129.                     dirty=1;
  1130.                 }
  1131.             }
  1132.         }
  1133.         if(    dirty != 0 )
  1134.         {
  1135.             toaplan1_fillbgmask(
  1136.                 tmpbitmap2,                // dist
  1137.                 tmpbitmap3,                // mask
  1138.                 &sp_rect,
  1139.                 palette_transparent_pen
  1140.             );
  1141.         }
  1142.         copybitmap(bitmap, tmpbitmap2, 0, 0, 0, 0, &sp_rect, TRANSPARENCY_PEN, palette_transparent_pen);
  1143.         tinfo2++;
  1144.         }
  1145.     }
  1146.  
  1147. #ifdef BGDBG
  1148. }
  1149. #endif
  1150.  
  1151. }
  1152.  
  1153.  
  1154. static void rallybik_render (struct osd_bitmap *bitmap)
  1155. {
  1156.     int i;
  1157.     int priority,pen;
  1158.     tile_struct *tinfo;
  1159.  
  1160.     fillbitmap (bitmap, palette_transparent_pen, &Machine->drv->visible_area);
  1161.  
  1162.     for ( priority = 0 ; priority < 16 ; priority++ )    /* draw priority layers in order */
  1163.     {
  1164.         tinfo = (tile_struct *)&(tile_list[priority][0]) ;
  1165.         /* hack to fix black blobs in Demon's World sky */
  1166.         if ( priority == 1 )
  1167.             pen = TRANSPARENCY_NONE ;
  1168.         else
  1169.             pen = TRANSPARENCY_PEN ;
  1170.         for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
  1171.         {
  1172.             /* hack to fix blue blobs in Zero Wing attract mode */
  1173.             if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
  1174.                 pen = TRANSPARENCY_PEN ;
  1175.  
  1176.             drawgfx(bitmap,Machine->gfx[(tinfo->color>>7)&1],    /* bit 7 set for sprites */
  1177.                 tinfo->tile_num,
  1178.                 (tinfo->color&0x3f),             /* bit 7 not for colour */
  1179.                 (tinfo->color & 0x0100),(tinfo->color & 0x0200),    /* flipx,flipy */
  1180.                 tinfo->xpos,tinfo->ypos,
  1181.                 &Machine->drv->visible_area,pen,0);
  1182.             tinfo++ ;
  1183.         }
  1184.     }
  1185. }
  1186.  
  1187.  
  1188. void toaplan1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1189. {
  1190.     /* discover what data will be drawn */
  1191.     toaplan1_find_sprites();
  1192.     toaplan1_find_tiles(tiles_offsetx,tiles_offsety);
  1193.  
  1194.     toaplan1_update_palette();
  1195.     toaplan1_render(bitmap);
  1196. }
  1197.  
  1198. void rallybik_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1199. {
  1200.     /* discover what data will be drawn */
  1201.     rallybik_find_tiles();
  1202.     rallybik_find_sprites();
  1203.  
  1204.     toaplan1_update_palette();
  1205.     rallybik_render(bitmap);
  1206. }
  1207.  
  1208.  
  1209.  
  1210. /****************************************************************************
  1211.     Spriteram is always 1 frame ahead, suggesting spriteram buffering.
  1212.     There are no CPU output registers that control this so we
  1213.     assume it happens automatically every frame, at the end of vblank
  1214. ****************************************************************************/
  1215.  
  1216. void toaplan1_eof_callback(void)
  1217. {
  1218.     memcpy(toaplan1_buffered_videoram1,toaplan1_videoram1,VIDEORAM1_SIZE);
  1219.     memcpy(toaplan1_buffered_videoram2,toaplan1_videoram2,VIDEORAM2_SIZE);
  1220. }
  1221.  
  1222. void rallybik_eof_callback(void)
  1223. {
  1224.     buffer_spriteram_w(0,0);
  1225. }
  1226.  
  1227. void samesame_eof_callback(void)
  1228. {
  1229.     memcpy(toaplan1_buffered_videoram1,toaplan1_videoram1,VIDEORAM1_SIZE);
  1230.     memcpy(toaplan1_buffered_videoram2,toaplan1_videoram2,VIDEORAM2_SIZE);
  1231.     cpu_set_irq_line(0, MC68000_IRQ_2, HOLD_LINE);  /* Frame done */
  1232. }
  1233.  
  1234.